#include "inverse.h"
#include "../libpresenter/presenter.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

int inverseTransform(void (*fun)(unsigned char *), void (*inv)(unsigned char *),
		     unsigned char *state) {
	unsigned char tmp[8];
	memcpy(tmp, state, sizeof(char[8]));

	fun(tmp);
	inv(tmp);

	return memcmp(state, tmp, sizeof(char[8]));
}

int randomInverseTransform(void (*fun)(unsigned char *), 
			   void (*inv)(unsigned char *), int count) {
	unsigned char tmp[8];

	for(int i = 0; i < count; ++i) {
		for(int j = 0; j < 8; ++j)
			tmp[j] = rand() % 0xFF;

		if(inverseTransform(fun, inv, tmp) != 0)
			return 1;
	}

	return 0;
}

int inverseCipher(unsigned char *state, unsigned char expandedKeys[][8]) {
	unsigned char tmp[8];
	memcpy(tmp, state, sizeof(char[8]));

	cipher(tmp, expandedKeys);
	inv_cipher(tmp, expandedKeys);

	return memcmp(state, tmp, sizeof(char[8]));
}

int randomInverseCipher(unsigned char expandedKeys[][8], int count) {
	unsigned char tmp[8];

	for(int i = 0; i < count; ++i) {
		for(int j = 0; j < 8; ++j)
			tmp[j] = rand() % 0xFF;

		if(inverseCipher(tmp, expandedKeys) != 0)
			return 1;
	}

	return 0;
}

int autoInverseCipherTest(int count) {
	unsigned char key[10];
	unsigned char expandedKeys[32][8];

	for(int i = 0; i < count; ++i) {
		for(int j = 0; j < 10; ++j)
			key[j] = rand() % 0xFF;

		generateRoundKeys(key, expandedKeys);

		if(randomInverseCipher(expandedKeys, count) != 0)
			return 1;
	}

	return 0;
}

